module("ufe.util.shared",package.seeall)
local conf = require("ufe.config")
local cjson = require("cjson.safe")

local ufe_apps_key = "ufe_apps"
local ufe_switch_key = "ufe_switch"

local function lock(key,expired)
    --exipired time is 20s,so we must do everything is 20s
    expired = expired or 20
    local success, msg = ufe_lock:add(key, 1, expired)
    return success
end
local function unlock(key)
    ufe_lock:delete(key)
end

function lock_ufe_apps()
    return lock(ufe_apps_key)
end


function unlock_ufe_apps()
    unlock(ufe_apps_key)
end

function lock_app(app)
    return lock(app)
end

function unlock_app(app)
    unlock(app)
end


function set_ufe_apps(apps)
    return shared_conf:set(ufe_apps_key,apps)
end

function get_ufe_apps()
    return shared_conf:get(ufe_apps_key)
end

function set_app_conf(app, conf)
    return shared_conf:set("ufe_"..app, conf)
end

function get_app_conf(app)
    return shared_conf:get("ufe_"..app)
end

function clear_app_conf(app)
    return shared_conf:delete("ufe_"..app)
end

function is_ufe_apps_done()
    return (get_ufe_apps() ~= nil)
end


function clear_loaded_conf()
    ngx.log(ngx.NOTICE, "clear all loaded conf")
    shared_conf:flush_all()
    --[[local apps_str = get_ufe_apps()
    shared_conf:delete(ufe_apps_key)
    -- delete all app conf
    local apps, err = cjson.decode(apps_str)
    if apps then
        for _, app in ipairs(apps.ufe_apps) do
            clear_app_conf(app)
        end
    else
        err = err or "known error"
        ngx.log(ngx.ERR, "the apps in shared dict is wrong, unexpected!" .. err)
    end]]--
end

function get_switch_raw()
    return shared_conf:get(ufe_switch_key)
end
function get_switch()
    local switch_conf = get_switch_raw()
    local cjson = require("cjson.safe")
    local switch = {}
    if switch_conf then
         switch = cjson.decode(switch_conf)
         if not switch then
             switch = {}
             ngx.log(ngx.ERR, "the switch_conf in shared conf is error. unexpected:",switch_conf)
         end
    end
    return switch
end

function set_ufe_switch_locked(status,app)
    local switch = get_switch()

    if app then
        switch[app] = status
    else
        switch.global = status
    end

    switch_conf = cjson.encode(switch)
    return shared_conf:set(ufe_switch_key, switch_conf)
end

function set_ufe_switch(status,app)
    --expired is 3s
    if not lock(ufe_switch_key,3) then
        return false, "someone is trying to set status, please try later."
    end
    local success, err = set_ufe_switch_locked(status,app)
    if not success then
        unlock(ufe_switch_key)
        return false, "setting switch error:"..err
    end
    unlock(ufe_switch_key)
    return true
end

function set_ufe_err(err)
    return shared_conf:set(ufe_apps_key.."_error",err)
end

function get_ufe_err()
    return shared_conf:get(ufe_apps_key.."_error")
end

function set_app_err(app, err)
    return shared_conf:set("ufe_"..app.."_error", err)
end

function get_app_err(app)
    return shared_conf:get("ufe_"..app.."_error")
end
